﻿using BodaNetCommunications.Cores;
using BodaNetCommunications.Utilities.Tools;

namespace BodaNetCommunications.S7Coms.S7Utils
{
    /// <summary>
    ///  大小端的转换
    /// </summary>
    public class S7ByteTransformBase : ByteTransformBase
    {
        /// <summary>
        /// S7-200/200 SMART  采用大端
        /// S7-1200/1500，优化的块（Optimized block）存储使用Little-Endian（小端对齐）
        /// </summary>
        public S7ByteTransformBase()
        {
            EndianType = Utilities.ComTypes.EndianType.ABCD;
        }

        /// <summary>
        /// 从缓存中提取short结果
        /// </summary>
        /// <param name="buffer">缓存数据</param>
        /// <param name="index">索引位置</param>
        /// <returns>short对象</returns>
        public override short TransInt16(byte[] buffer, int index)
        {
            var bytes = buffer.Skip(index * 2).Take(2).ToArray();
            var temp = bytes[1];
            bytes[1] = bytes[0];
            bytes[0] = temp;
            return BitConverter.ToInt16(bytes, 0);
        }


        /// <summary>
        /// short数组变量转化缓存数据
        /// </summary>
        /// <param name="values">等待转化的数组</param>
        /// <returns>buffer数据</returns>
        public override byte[] TransByte(short[] values)
        {
            byte[] buffer = new byte[values.Length * 2];
            for (int i = 0; i < values.Length; i++)
            {
                BitConverter.GetBytes(values[i]).CopyTo(buffer, 2 * i);
                var temp = buffer[i + 1];
                buffer[i + 1] = buffer[i];
                buffer[i] = temp;
            }
            return buffer;
        }

        /// <summary>
        /// DB块对应的数据类型
        /// </summary>
        private Dictionary<string, Type> _pValudDic = new Dictionary<string, Type>()
        {
            { "X",typeof(bool)},
            { "B",typeof(byte)},
            { "W",typeof(short)},
            { "D",typeof(int)},
            { "R",typeof(float)},
        };

        public override Type AnalysyseAddres<T>(string address, T value)
        {
            string str = address.Substring(0, 2);
            if (str.ToUpperInvariant() == "DB")
            {
                string[] arrays = address.Split('.');

                // 处理参数类型，比如：DB1.DBX1.1中的X
                string typeStr = arrays[1].Substring(2, 1);// X  B  W  D  R

                var dataType = _pValudDic[typeStr];
                return dataType;
            }

            return typeof(T);
        }


        public override bool AnalysyseAddresType(ref string address, out Type addressType)
        {
            addressType = null;
            string str = address.Substring(0, 2);
            if (str.ToUpperInvariant() == "DB")
            {
                string[] arrays = address.Split('.');

                // 处理参数类型，比如：DB1.DBX1.1中的X
                string typeStr = arrays[1].Substring(2, 1);// X  B  W  D  R

                addressType = _pValudDic[typeStr];

                // 处理位地址,比如：DBX1.DBW1.1，按照.分割位3部分
                if (arrays.Length == 3)
                {
                    if (typeStr == "X")
                    {
                        addressType = typeof(bool);
                    }
                    else
                    {
                        // 地址无法解析
                        throw Oops.Oh($"地址【{address}】无法解析");
                    }

                }

                return true;
            }

            return false;
        }

    }
}
